package se.hjartstartarregistret.m;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;

@SuppressWarnings("serial")
public class JSONServlet extends HttpServlet {

	private static byte[] compress(String str) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		byte b[] = str.getBytes();
		GZIPOutputStream gz = new GZIPOutputStream(bos, b.length);
		gz.write(b, 0, b.length);
		bos.close();
		gz.close();
		return bos.toByteArray();
	}

	public void service(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		Key jsonKey = KeyFactory.createKey("json", 1);
		DatastoreService datastore = DatastoreServiceFactory
				.getDatastoreService();

		if ("true".equals(req.getParameter("startQueue"))) {
			Queue queue = QueueFactory.getDefaultQueue();
			queue.add(TaskOptions.Builder.withUrl("/json").param("refresh",
					"true"));
			resp.getWriter().println("Queue started");
			return;
		} else if ("true".equals(req.getParameter("refresh"))) {
			System.out.println("Refreshing in queue");
			try {
				String generatedJson = KmlParser.parseKmlToJson();

				byte[] jsonGzippedBytes = compress(generatedJson);
				System.out.println("Done! About to store "
						+ generatedJson.length() + " characters compressed to "
						+ jsonGzippedBytes.length + " bytes");
				Entity jsonEntity = new Entity(jsonKey);
				jsonEntity.setProperty("json", new Blob(jsonGzippedBytes));
				datastore.put(jsonEntity);
				return;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		// App engine already does this:
		// resp.setHeader("Content-Encoding", "gzip");
		resp.setContentType("application/json");
		resp.setHeader("Access-Control-Allow-Origin", "*");

		try {
			Entity jsonEntity = datastore.get(jsonKey);
			byte[] storedJsonGzipped = (byte[]) ((Blob) jsonEntity
					.getProperty("json")).getBytes();

			GZIPInputStream gzis = new GZIPInputStream(
					new ByteArrayInputStream(storedJsonGzipped));
			OutputStream out = resp.getOutputStream();

			byte[] buffer = new byte[4096];
			int len;
			while ((len = gzis.read(buffer)) > 0) {
				out.write(buffer, 0, len);
			}
		} catch (EntityNotFoundException e1) {
			resp.sendError(HttpServletResponse.SC_NO_CONTENT);
			resp.getWriter().println("No content yet");
		}
	}
}
